package com.zhongwang.mms.module.buy.service;

import com.zhongwang.mms.common.ImportCallBack;
import com.zhongwang.mms.gen.entity.BReportPlan;
import com.zhongwang.mms.gen.entity.TDictionary;
import com.zhongwang.mms.gen.entity.TEmploy;
import com.zhongwang.mms.gen.entity.User;
import com.zhongwang.mms.gen.mapper.BReportPlanMapper;
import com.zhongwang.mms.module.basic.service.BoardService;
import com.zhongwang.mms.module.buy.dao.ReportPlanDao;
import com.zhongwang.mms.module.buy.listner.ImportReportPlanListener;
import com.zhongwang.mms.module.buy.model.ImportReportPlanModel;
import com.zhongwang.mms.module.buy.model.ReportPlanModel;
import com.zhongwang.mms.module.system.log.LogService;
import com.zhongwang.mms.util.CodeUtil;
import com.zhongwang.mms.util.FileUtils;
import com.zhongwang.mms.util.ShiroUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;

import static com.zhongwang.mms.util.BeanUtil.copy;

/**
 * @Description: 提报计划导入 Service
 *
 * @Author: China.sgl
 * @Date: 2020/4/7 16:25
 */
@SuppressWarnings("ALL")
@Service
public class ImportReportPlanService {
    @Autowired
    private BoardService boardService;
    @Autowired
    private LogService logService;
    @Autowired
    private ReportPlanDao reportPlanDao;
    @Autowired
    private BReportPlanMapper bReportPlanMapper;

    @Value("${user.upload.path}")
    private String uploadPath;

    private String msg = "";

    /**
     * 按条件查询提报计划
     *
     * @param reportPlanModel 条件
     * @return list
     */
    public List<ReportPlanModel> findReportPlanByQuery(ReportPlanModel reportPlanModel) {
        return reportPlanDao.findReportPlanByQueryWithImport(reportPlanModel);
    }

    /**
     * 查询项目号
     *
     * @param code 项目号
     * @return boolean
     */
    public boolean findProjectCode(String code) {
        return reportPlanDao.findProjectByCode(code) != null;
    }

    /**
     * 添加提报计划
     *
     * @param reportPlan 提报计划
     * @return 行数
     */
    @Transactional(rollbackFor = Exception.class)
    public int insertReportPlan(ReportPlanModel reportPlan) {
        if (reportPlan.getRppPlanner() == null || reportPlan.getRppMatDesc() == null
                || reportPlan.getRppNum() == null || reportPlan.getRppUnit() == null
                || reportPlan.getRppProjectCode() == null || reportPlan.getRppProjectName() == null
                || reportPlanDao.findExist(reportPlan) > 0) {
            return 0;
        }
        TDictionary category = reportPlanDao.findDictionaryByIdAndStatus(reportPlan.getRppTypeId(), 1);
        reportPlan.setRppProjectCode(boardService.projectCodeHandle(reportPlan.getRppProjectCode()));
        reportPlan.setRppTypes(category.getDicName());
        reportPlan.setRppCreateTime(new Date());
        reportPlan.setRppOriginalFlag(1);
        reportPlan.setRppStatus(-1);
        reportPlan.setRppAllowCancel(2);
        reportPlan.setRppAppend(0);
        reportPlan.setRppCreateUser(ShiroUtils.getUser().getName());
        reportPlan.setRppIsFlag(0);
        reportPlanDao.insert(reportPlan);
        return logService.saveLog("提报计划添加", "添加提报计划");
    }

    /**
     * 导入日报
     *
     * @param file 导入文件
     * @return
     */
    //@Transactional(rollbackFor = Exception.class)
    public String importFile(MultipartFile file) {
        try {
            FileUtils.importExcel(file, ImportReportPlanModel.class, new ImportReportPlanListener(reportPlanDao, new ImportCallBack() {
                @Override
                public void onSuccess() {
                    msg = "导入完成";
                }

                @Override
                public void onWarning(List list) {
                    msg = "部份数据无法导入，请点击下载检查数据内容";
                    exportErrorExcel(list);
                }
            }, reportPlanDao.findDictionaryByTypeAndStatus(1000, 1), reportPlanDao.findEmployByStatus(1)));
        } catch (IOException e) {
            return "导入失败";
        }
        logService.saveLog("提报计划导入", "导入提报计划");
        return msg;
    }

    /**
     * 异常数据导出到Excel
     *
     * @param errorList
     */
    private void exportErrorExcel(List<ReportPlanModel> errorList) {
        if (errorList.size() <= 0) {
            return;
        }
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        String path = uploadPath + user.getAccount() + "/";
        FileUtils.genExcel(path, "error.xls", ReportPlanModel.class, "未成功导入数据", errorList);
    }

    /**
     * 判断文件是否存在
     *
     * @param url 文件URL
     * @return 是否存在
     */
    public boolean exist(String url) {
        int i = url.lastIndexOf("files/");
        String path = uploadPath + url.substring(i + 6);
        File file = new File(path);
        if (!file.exists()) {
            return false;
        }
        return true;
    }

    /**
     * 根据ID修改提报计划状态并保存日志
     *
     * @param id 主键
     * @param status 状态
     * @param name 日志操作名称
     * @return 行数
     */
    private int updateReportPlanStatus(Integer id, Integer status, String name) {
        ReportPlanModel plan = findReportPlanById(id);
        logService.saveLog(name, "项目名：" + plan.getRppProjectName() + "<br>物料描述：" + plan.getRppMatDesc());
        return reportPlanDao.updateStatusById(id, status);
    }

    /**
     * 删除提报计划
     *
     * @param id 主键
     * @return 行数
     */
    public int deleteById(Integer id) {
        return updateReportPlanStatus(id, -2, "删除采购计划");
    }

    /**
     * 批量删除提报计划
     *
     * @param rppIds 提报计划ID数组
     * @return 行数
     */
    @Transactional(rollbackFor = Exception.class)
    public int deleteInId(Integer[] rppIds) {
        int count = 0;
        // 保存日志，生成采购计划
        for (Integer rppId : rppIds) {
            count += deleteById(rppId);
        }
        return count == rppIds.length ? 1 : 0;
    }



    /**
     * 提交提报计划
     *
     * @param id 主键
     * @return 行数
     */
    public int commitById(Integer id) {
        return updateReportPlanStatus(id, 2, "提交提报计划");
    }

    /**
     * 批量提交提报计划
     *
     * @param rppIds 提报计划ID数组
     * @return 行数
     */
    @Transactional(rollbackFor = Exception.class)
    public int commitInId(Integer[] rppIds) {
        int count = 0;
        // 保存日志，生成采购计划
        for (Integer rppId : rppIds) {
            count += commitById(rppId);
        }
        return count == rppIds.length ? 1 : 0;
    }

    /**
     * 根据主键查询提报计划
     *
     * @param id 主键
     * @return ReportPlanModel
     */
    public ReportPlanModel findReportPlanById(Integer id) {
        return reportPlanDao.findReportPlanById(id);
    }

    /**
     * 修改提报计划
     *
     * @param reportPlan 提报计划
     * @return 行数
     */
    public int updateReportPlan(BReportPlan reportPlan) {
        BReportPlan before = bReportPlanMapper.selectByPrimaryKey(reportPlan.getRppId());
        BReportPlan after = new BReportPlan();
        copy(before, after);
        copy(reportPlan, after);
        // 设置分类名称
        TDictionary category = reportPlanDao.findDictionaryByIdAndStatus(after.getRppTypeId(), 1);
        after.setRppTypes(category.getDicName());
        // 保存日志
        logService.saveLog("修改提报计划", before, after);

        return reportPlanDao.update(after);
    }

    /**
     * 查询分类列表
     *
     * @return list
     */
    public List<TDictionary> findTypes() {
        return reportPlanDao.findDictionaryByTypeAndStatus(1000, 1);
    }

    /**
     * 查询计划员列表
     *
     * @return list
     */
    public List<TEmploy> findPlannerList() {
        return reportPlanDao.findEmployByStatus(1);
    }
}
